In [1]:
Copied!
import pathpyG as pp
import torch
from pathpyG.nn.dbgnn import DBGNN
from torch_geometric.transforms import RandomNodeSplit
import torch_geometric
from sklearn.manifold import TSNE
import numpy as np
import matplotlib.pyplot as plt
pp.config['torch']['device'] = 'cpu'
device = pp.config['torch']['device']
import pathpyG as pp
import torch
from pathpyG.nn.dbgnn import DBGNN
from torch_geometric.transforms import RandomNodeSplit
import torch_geometric
from sklearn.manifold import TSNE
import numpy as np
import matplotlib.pyplot as plt
pp.config['torch']['device'] = 'cpu'
device = pp.config['torch']['device']
Load the synthetic dataset¶
In [34]:
Copied!
# Read temporal network
t = pp.TemporalGraph.from_csv('../data/temporal_clusters.tedges')
# Read temporal network
t = pp.TemporalGraph.from_csv('../data/temporal_clusters.tedges')
In [3]:
Copied!
node_colors = ['green']*10+['red']*10+['blue']*10
node_colors = ['green']*10+['red']*10+['blue']*10
In [4]:
Copied!
style = {}
style['node_color'] = node_colors
style = {}
style['node_color'] = node_colors
In [5]:
Copied!
pp.plot(t, **style);
pp.plot(t, **style);
In [35]:
Copied!
# generate DAG of causally connected node-time events
dag = pp.algorithms.temporal_graph_to_event_dag(t, delta=1)
print(dag)
# generate DAG of causally connected node-time events
dag = pp.algorithms.temporal_graph_to_event_dag(t, delta=1)
print(dag)
Graph with 89032 nodes and 60000 edges Node attributes node_id <class 'list'> node_name <class 'list'> node_idx <class 'list'> Edge attributes edge_ts <class 'torch.Tensor'> -> torch.Size([60000]) Graph attributes num_nodes <class 'int'>
In [36]:
Copied!
# compute time-respecting paths in this DAG
paths = pp.PathData.from_temporal_dag(dag)
paths.node_id = t.data.node_id
print(paths)
# compute time-respecting paths in this DAG
paths = pp.PathData.from_temporal_dag(dag)
paths.node_id = t.data.node_id
print(paths)
PathData with 29032 walks and 0 dags and total weight 29032
In [37]:
Copied!
# Create the graph corresponding to paths
g = pp.HigherOrderGraph(paths, order=1)
# Plotting the time-aggregated network (first-order graph)
pp.plot(g, edge_width=1.5);
# Create the graph corresponding to paths
g = pp.HigherOrderGraph(paths, order=1)
# Plotting the time-aggregated network (first-order graph)
pp.plot(g, edge_width=1.5);
In [38]:
Copied!
# Create the second-order graph corresponding to paths
g2 = pp.HigherOrderGraph(paths, order=2)
# Plotting the second-order graph
pp.plot(g2);
# Create the second-order graph corresponding to paths
g2 = pp.HigherOrderGraph(paths, order=2)
# Plotting the second-order graph
pp.plot(g2);
In [39]:
Copied!
t_shuffled = pp.TemporalGraph.from_csv('../data/temporal_clusters.tedges')
t_shuffled.data['t'] = t.data['t'][torch.randperm(len(t_shuffled.data['t']))]
t_shuffled = pp.TemporalGraph.from_csv('../data/temporal_clusters.tedges')
t_shuffled.data['t'] = t.data['t'][torch.randperm(len(t_shuffled.data['t']))]
In [40]:
Copied!
t.data.t
t.data.t
Out[40]:
tensor([ 0, 1, 2, ..., 59997, 59998, 59999])
In [41]:
Copied!
t_shuffled.data.t
t_shuffled.data.t
Out[41]:
tensor([25615, 56612, 8066, ..., 31437, 36506, 2195])
In [42]:
Copied!
#caluclate paths
dag_shuffled = pp.algorithms.temporal_graph_to_event_dag(t_shuffled, delta=1)
print(dag_shuffled)
#caluclate paths
dag_shuffled = pp.algorithms.temporal_graph_to_event_dag(t_shuffled, delta=1)
print(dag_shuffled)
Graph with 117974 nodes and 60000 edges Node attributes node_id <class 'list'> node_name <class 'list'> node_idx <class 'list'> Edge attributes edge_ts <class 'torch.Tensor'> -> torch.Size([60000]) Graph attributes num_nodes <class 'int'>
In [43]:
Copied!
paths_shuffled = pp.PathData.from_temporal_dag(dag_shuffled)
print(paths_shuffled)
print(paths_shuffled.num_nodes)
paths_shuffled = pp.PathData.from_temporal_dag(dag_shuffled)
print(paths_shuffled)
print(paths_shuffled.num_nodes)
PathData with 57974 walks and 0 dags and total weight 57974 30
In [44]:
Copied!
# Create the second-order graph corresponding to paths
g2_shuffled = pp.HigherOrderGraph(paths_shuffled, order=2)
print(g2_shuffled)
# Plotting the second-order graph
pp.plot(g2_shuffled);
# Create the second-order graph corresponding to paths
g2_shuffled = pp.HigherOrderGraph(paths_shuffled, order=2)
print(g2_shuffled)
# Plotting the second-order graph
pp.plot(g2_shuffled);
HigherOrderGraph (k=2) with 860 nodes and 1918 edges Total edge weight = 2026.0 Edge attributes edge_weight <class 'torch.Tensor'> -> torch.Size([1918]) Graph attributes node_id <class 'list'> num_nodes <class 'int'>
Prepare the data¶
In [45]:
Copied!
# Define edge indices for first and second-order graphs
edge_index_g1 = g.data.edge_index
edge_index_g2 = g2.data.edge_index
# Define edge indices for first and second-order graphs
edge_index_g1 = g.data.edge_index
edge_index_g2 = g2.data.edge_index
In [46]:
Copied!
# Define edge weights
edge_weights = g.data['edge_weight']
edge_weights_higher_order = g2.data['edge_weight']
# Define edge weights
edge_weights = g.data['edge_weight']
edge_weights_higher_order = g2.data['edge_weight']
In [47]:
Copied!
# Define bipartite mapping
import torch
def generate_bipatite_edge_index(mapping = 'last'):
if mapping == 'last':
bipartide_edge_index = torch.tensor([list(g2.node_index_to_id.keys()),
[i[1] for i in g2.node_index_to_id.values()]])
elif mapping == 'first':
bipartide_edge_index = torch.tensor([list(g2.node_index_to_id.keys()),
[i[0] for i in g2.node_index_to_id.values()]])
else:
bipartide_edge_index = torch.tensor([list(g2.node_index_to_id.keys()) + list(g2.node_index_to_id.keys()),
[i[0] for i in g2.node_index_to_id.values()] + [i[1] for i in g2.node_index_to_id.values()]])
return bipartide_edge_index
# Original DBGNN implementation mapping = 'last'
bipatite_edge_index = generate_bipatite_edge_index(mapping='last')
# Define bipartite mapping
import torch
def generate_bipatite_edge_index(mapping = 'last'):
if mapping == 'last':
bipartide_edge_index = torch.tensor([list(g2.node_index_to_id.keys()),
[i[1] for i in g2.node_index_to_id.values()]])
elif mapping == 'first':
bipartide_edge_index = torch.tensor([list(g2.node_index_to_id.keys()),
[i[0] for i in g2.node_index_to_id.values()]])
else:
bipartide_edge_index = torch.tensor([list(g2.node_index_to_id.keys()) + list(g2.node_index_to_id.keys()),
[i[0] for i in g2.node_index_to_id.values()] + [i[1] for i in g2.node_index_to_id.values()]])
return bipartide_edge_index
# Original DBGNN implementation mapping = 'last'
bipatite_edge_index = generate_bipatite_edge_index(mapping='last')
In [48]:
Copied!
# Define the PyG data object
from torch_geometric.data import Data
num_nodes = max(max(g.data['edge_index'][0]), max(g.data['edge_index'][1])).item() + 1 # since indexing starts from 0
num_ho_nodes = max(max(g2.data['edge_index'][0]), max(g2.data['edge_index'][1])).item() + 1 # since indexing starts from 0
data = Data(
num_nodes = num_nodes,
num_ho_nodes = num_ho_nodes,
x = torch.eye(num_nodes, num_nodes),
x_h = torch.eye(num_ho_nodes, num_ho_nodes),
edge_index = edge_index_g1,
edge_index_higher_order = edge_index_g2,
edge_weights = edge_weights.float(),
edge_weights_higher_order = edge_weights_higher_order.float(),
bipartite_edge_index = bipatite_edge_index,
y = torch.tensor([ int(i) // 10 for i in paths.node_id])
)
# Define the PyG data object
from torch_geometric.data import Data
num_nodes = max(max(g.data['edge_index'][0]), max(g.data['edge_index'][1])).item() + 1 # since indexing starts from 0
num_ho_nodes = max(max(g2.data['edge_index'][0]), max(g2.data['edge_index'][1])).item() + 1 # since indexing starts from 0
data = Data(
num_nodes = num_nodes,
num_ho_nodes = num_ho_nodes,
x = torch.eye(num_nodes, num_nodes),
x_h = torch.eye(num_ho_nodes, num_ho_nodes),
edge_index = edge_index_g1,
edge_index_higher_order = edge_index_g2,
edge_weights = edge_weights.float(),
edge_weights_higher_order = edge_weights_higher_order.float(),
bipartite_edge_index = bipatite_edge_index,
y = torch.tensor([ int(i) // 10 for i in paths.node_id])
)
DBGNN¶
In [49]:
Copied!
from sklearn.metrics import balanced_accuracy_score
def test(model, data):
model.eval()
_, pred = model(data).max(dim=1)
metrics_train = balanced_accuracy_score(
data.y[data.train_mask].cpu(),
pred[data.train_mask].cpu().numpy()
)
metrics_test = balanced_accuracy_score(
data.y[data.test_mask].cpu(),
pred[data.test_mask].cpu().numpy()
)
return metrics_train, metrics_test
from sklearn.metrics import balanced_accuracy_score
def test(model, data):
model.eval()
_, pred = model(data).max(dim=1)
metrics_train = balanced_accuracy_score(
data.y[data.train_mask].cpu(),
pred[data.train_mask].cpu().numpy()
)
metrics_test = balanced_accuracy_score(
data.y[data.test_mask].cpu(),
pred[data.test_mask].cpu().numpy()
)
return metrics_train, metrics_test
In [50]:
Copied!
data = RandomNodeSplit(num_val=0, num_test=0.3)(data)
model = DBGNN(
num_features =[num_nodes, num_ho_nodes],
num_classes = len(data.y.unique()),
hidden_dims = [16, 32, 8],
p_dropout = 0.4
).to(device)
optimizer = torch.optim.Adam(model.parameters(), lr=0.005)
loss_function = torch.nn.CrossEntropyLoss()
data = data.to(device)
data = RandomNodeSplit(num_val=0, num_test=0.3)(data)
model = DBGNN(
num_features =[num_nodes, num_ho_nodes],
num_classes = len(data.y.unique()),
hidden_dims = [16, 32, 8],
p_dropout = 0.4
).to(device)
optimizer = torch.optim.Adam(model.parameters(), lr=0.005)
loss_function = torch.nn.CrossEntropyLoss()
data = data.to(device)
In [51]:
Copied!
data.y
data.y
Out[51]:
tensor([0, 2, 1, 1, 0, 2, 0, 0, 0, 1, 2, 0, 2, 2, 1, 1, 2, 2, 1, 1, 0, 2, 0, 0,
1, 1, 2, 0, 2, 1])
In [52]:
Copied!
print(model)
print(model)
DBGNN(
(higher_order_layers): ModuleList(
(0): GCNConv(557, 16)
(1): GCNConv(16, 32)
)
(first_order_layers): ModuleList(
(0): GCNConv(30, 16)
(1): GCNConv(16, 32)
)
(bipartite_layer): BipartiteGraphOperator()
(lin): Linear(in_features=8, out_features=3, bias=True)
)
In [53]:
Copied!
losses = []
for epoch in range(1000):
output = model(data)
loss = loss_function(output[data.train_mask], data.y[data.train_mask])
loss.backward()
optimizer.step()
optimizer.zero_grad()
losses.append(loss)
if epoch % 10 == 0:
train_ba, test_ba = test(model, data)
print(f'Epoch: {epoch}, Loss: {loss}, Train balanced accuracy: {train_ba}, Test balanced accuracy: {test_ba}')
losses = []
for epoch in range(1000):
output = model(data)
loss = loss_function(output[data.train_mask], data.y[data.train_mask])
loss.backward()
optimizer.step()
optimizer.zero_grad()
losses.append(loss)
if epoch % 10 == 0:
train_ba, test_ba = test(model, data)
print(f'Epoch: {epoch}, Loss: {loss}, Train balanced accuracy: {train_ba}, Test balanced accuracy: {test_ba}')
Epoch: 0, Loss: 1.4318904876708984, Train balanced accuracy: 0.3333333333333333, Test balanced accuracy: 0.3333333333333333 Epoch: 10, Loss: 0.5897860527038574, Train balanced accuracy: 0.6666666666666666, Test balanced accuracy: 0.6666666666666666 Epoch: 20, Loss: 0.16737990081310272, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 30, Loss: 0.005376117769628763, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 40, Loss: 0.0007377972942776978, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 50, Loss: 0.0002963749866466969, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 60, Loss: 0.00014648483193013817, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 70, Loss: 9.813800716074184e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 80, Loss: 7.852899580029771e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 90, Loss: 6.807437603129074e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 100, Loss: 6.125211075413972e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 110, Loss: 5.6092776503646746e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 120, Loss: 5.188694194657728e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 130, Loss: 4.827136217500083e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 140, Loss: 4.5104152377462015e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 150, Loss: 4.2305862734792754e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 160, Loss: 3.976865264121443e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 170, Loss: 3.7498200981644914e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 180, Loss: 3.544343417161144e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 190, Loss: 3.352488420205191e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 200, Loss: 3.180499697919004e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 210, Loss: 3.0221328415791504e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 220, Loss: 2.874550045817159e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 230, Loss: 2.7394551580073312e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 240, Loss: 2.611739000712987e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 250, Loss: 2.4953749743872322e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 260, Loss: 2.3852540834923275e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 270, Loss: 2.2836477000964805e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 280, Loss: 2.1882853616261855e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 290, Loss: 2.100869460264221e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 300, Loss: 2.0145889720879495e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 310, Loss: 1.9368222638149746e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 320, Loss: 1.8630291378940456e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 330, Loss: 1.7937774828169495e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 340, Loss: 1.727931339701172e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 350, Loss: 1.6660584151395597e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 360, Loss: 1.6092943042167462e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 370, Loss: 1.553097717987839e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 380, Loss: 1.499171594332438e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 390, Loss: 1.4503541933663655e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 400, Loss: 1.4026721146365162e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 410, Loss: 1.3589634363597725e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 420, Loss: 1.315822282776935e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 430, Loss: 1.2743842489726376e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 440, Loss: 1.2335136489127763e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 450, Loss: 1.1977517715422437e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 460, Loss: 1.1619899851211812e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 470, Loss: 1.1284988431725651e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 480, Loss: 1.0955752259178553e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 490, Loss: 1.064922344085062e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 500, Loss: 1.0365399248257745e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 510, Loss: 1.0075897080241702e-05, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 520, Loss: 9.797748134587891e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 530, Loss: 9.542305633658543e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 540, Loss: 9.298216355091427e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 550, Loss: 9.059802323463373e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 560, Loss: 8.832742423692252e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 570, Loss: 8.60568161442643e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 580, Loss: 8.401327249885071e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 590, Loss: 8.191295819415245e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 600, Loss: 7.986941454873886e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 610, Loss: 7.793938493705355e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 620, Loss: 7.617967185069574e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 630, Loss: 7.436317446263274e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 640, Loss: 7.24899200577056e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 650, Loss: 7.09572577761719e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 660, Loss: 6.948137524886988e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 670, Loss: 6.772163942514453e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 680, Loss: 6.647279406024609e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 690, Loss: 6.4940131778712384e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 700, Loss: 6.3521001720801e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 710, Loss: 6.215862867975375e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 720, Loss: 6.096655852161348e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 730, Loss: 5.977447926852619e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 740, Loss: 5.835534011566779e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 750, Loss: 5.739032530982513e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 760, Loss: 5.6141484492400195e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 770, Loss: 5.494940978678642e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 780, Loss: 5.398439498094376e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 790, Loss: 5.2792320275329985e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 800, Loss: 5.177053935767617e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 810, Loss: 5.097582288726699e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 820, Loss: 5.001080808142433e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 830, Loss: 4.904578872810816e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 840, Loss: 4.79672462461167e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 850, Loss: 4.722929588751867e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 860, Loss: 4.632103809854016e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 870, Loss: 4.558309228741564e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 880, Loss: 4.490190349315526e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 890, Loss: 4.405041636346141e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 900, Loss: 4.319892923376756e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 910, Loss: 4.240421276335837e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 920, Loss: 4.166625785728684e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 930, Loss: 4.1041835174837615e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 940, Loss: 4.024710960948141e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 950, Loss: 3.967945758631686e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 960, Loss: 3.905503490386764e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 970, Loss: 3.837384610960726e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 980, Loss: 3.7692650494136615e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0 Epoch: 990, Loss: 3.7124996197235305e-06, Train balanced accuracy: 1.0, Test balanced accuracy: 1.0
Latent space representation of edges¶
In [54]:
Copied!
g2.node_index_to_id[0]
g2.node_index_to_id[0]
Out[54]:
(0, 1)
In [55]:
Copied!
model.eval()
latent = model.higher_order_layers[0].forward(data.x_h, data.edge_index_higher_order).detach()
node_embedding = TSNE(n_components=2, learning_rate='auto', init='random').fit_transform(latent.cpu())
colors = []
for v, w in g2.nodes:
if data.y[v] == 0 and data.y[w] == 0:
colors.append('red')
elif data.y[v] == 1 and data.y[w] == 1:
colors.append('green')
elif data.y[v] == 2 and data.y[w] == 2:
colors.append('blue')
else:
colors.append('grey')
plt.figure(figsize=(13,10))
plt.scatter(node_embedding[:,0], node_embedding[:,1], c=colors, alpha=0.5)
for e in g2.edges:
s = g2.node_id_to_index[e[0]]
t = g2.node_id_to_index[e[1]]
plt.plot([node_embedding[s,0], node_embedding[t,0]], [node_embedding[s,1], node_embedding[t,1]],
color='lightsteelblue',
linestyle='-',
alpha=0.2,
lw=0.2)
plt.axis('off')
plt.show()
model.eval()
latent = model.higher_order_layers[0].forward(data.x_h, data.edge_index_higher_order).detach()
node_embedding = TSNE(n_components=2, learning_rate='auto', init='random').fit_transform(latent.cpu())
colors = []
for v, w in g2.nodes:
if data.y[v] == 0 and data.y[w] == 0:
colors.append('red')
elif data.y[v] == 1 and data.y[w] == 1:
colors.append('green')
elif data.y[v] == 2 and data.y[w] == 2:
colors.append('blue')
else:
colors.append('grey')
plt.figure(figsize=(13,10))
plt.scatter(node_embedding[:,0], node_embedding[:,1], c=colors, alpha=0.5)
for e in g2.edges:
s = g2.node_id_to_index[e[0]]
t = g2.node_id_to_index[e[1]]
plt.plot([node_embedding[s,0], node_embedding[t,0]], [node_embedding[s,1], node_embedding[t,1]],
color='lightsteelblue',
linestyle='-',
alpha=0.2,
lw=0.2)
plt.axis('off')
plt.show()
In [30]:
Copied!
model.eval()
latent = model.higher_order_layers[1].forward(latent.cpu(), data.edge_index_higher_order).detach()
node_embedding = TSNE(n_components=2, learning_rate='auto', init='random').fit_transform(latent.cpu())
colors = []
for v, w in g2.nodes:
if data.y[v] == 0 and data.y[w] == 0:
colors.append('red')
elif data.y[v] == 1 and data.y[w] == 1:
colors.append('green')
elif data.y[v] == 2 and data.y[w] == 2:
colors.append('blue')
else:
colors.append('grey')
plt.figure(figsize=(13,10))
plt.scatter(node_embedding[:,0], node_embedding[:,1], c=colors, alpha=0.5)
for e in g2.edges:
s = g2.node_id_to_index[e[0]]
t = g2.node_id_to_index[e[1]]
plt.plot([node_embedding[s,0], node_embedding[t,0]], [node_embedding[s,1], node_embedding[t,1]],
color='lightsteelblue',
linestyle='-',
alpha=0.2,
lw=0.2)
plt.axis('off')
plt.show()
model.eval()
latent = model.higher_order_layers[1].forward(latent.cpu(), data.edge_index_higher_order).detach()
node_embedding = TSNE(n_components=2, learning_rate='auto', init='random').fit_transform(latent.cpu())
colors = []
for v, w in g2.nodes:
if data.y[v] == 0 and data.y[w] == 0:
colors.append('red')
elif data.y[v] == 1 and data.y[w] == 1:
colors.append('green')
elif data.y[v] == 2 and data.y[w] == 2:
colors.append('blue')
else:
colors.append('grey')
plt.figure(figsize=(13,10))
plt.scatter(node_embedding[:,0], node_embedding[:,1], c=colors, alpha=0.5)
for e in g2.edges:
s = g2.node_id_to_index[e[0]]
t = g2.node_id_to_index[e[1]]
plt.plot([node_embedding[s,0], node_embedding[t,0]], [node_embedding[s,1], node_embedding[t,1]],
color='lightsteelblue',
linestyle='-',
alpha=0.2,
lw=0.2)
plt.axis('off')
plt.show()
Latent space representation of nodes¶
In [31]:
Copied!
model.eval()
latent = model.forward(data).detach()
node_embedding = TSNE(n_components=2, learning_rate='auto', init='random', perplexity=10).fit_transform(latent.cpu())
colors = []
for v in g.nodes:
if data.y[v] == 0:
colors.append('red')
elif data.y[v] == 1:
colors.append('green')
elif data.y[v] == 2:
colors.append('blue')
else:
colors.append('grey')
plt.figure(figsize=(13,10))
plt.scatter(node_embedding[:,0], node_embedding[:,1], c=colors, alpha=0.5)
for e in g.edges:
s = e[0]
t = e[1]
plt.plot([node_embedding[s,0], node_embedding[t,0]], [node_embedding[s,1], node_embedding[t,1]],
color='lightsteelblue',
linestyle='-',
alpha=0.2,
lw=0.2)
plt.axis('off')
plt.show()
model.eval()
latent = model.forward(data).detach()
node_embedding = TSNE(n_components=2, learning_rate='auto', init='random', perplexity=10).fit_transform(latent.cpu())
colors = []
for v in g.nodes:
if data.y[v] == 0:
colors.append('red')
elif data.y[v] == 1:
colors.append('green')
elif data.y[v] == 2:
colors.append('blue')
else:
colors.append('grey')
plt.figure(figsize=(13,10))
plt.scatter(node_embedding[:,0], node_embedding[:,1], c=colors, alpha=0.5)
for e in g.edges:
s = e[0]
t = e[1]
plt.plot([node_embedding[s,0], node_embedding[t,0]], [node_embedding[s,1], node_embedding[t,1]],
color='lightsteelblue',
linestyle='-',
alpha=0.2,
lw=0.2)
plt.axis('off')
plt.show()
In [ ]:
Copied!